---
title: Tutorial - Ampliar con View Transitions
description: >-
  Añade View Transitions al código del tutorial Crear un Blog
i18nReady: true
---
import { Steps } from '@astrojs/starlight/components';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import Box from '~/components/tutorial/Box.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import Spoiler from '~/components/Spoiler.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import ReadMore from '~/components/ReadMore.astro'

Las **View transitions** son una forma de controlar lo que sucede cuando los visitantes navegan entre páginas en tu sitio. La API de View Transitions de Astro te permite agregar funciones opcionales de navegación, como transiciones suaves entre páginas y animaciones, controlar la pila de historial del navegador de las páginas visitadas y evitar actualizaciones completas de la página para persistir algunos elementos y el estado de la página mientras se actualiza el contenido mostrado.

<PreCheck>
  - Importar y añadir el enrutador `<ViewTransitions />` a un elemento `head` común
  - Agregar listeners de eventos durante el proceso de navegación para activar `<script>` según sea necesario
  - Añadir animaciones de transición de página utilizando directivas de transición
  - Excluir la navegación del lado del cliente para un enlace de página individual
</PreCheck>

## Prerrequisitos

Necesitarás **un proyecto de Astro existente con una plantilla de base común o un componente `<Head />`**.

Este tutorial utiliza el [proyecto terminado del tutorial Crear un Blog](https://github.com/withastro/blog-tutorial-demo) para demostrar cómo agregar view transitions (navegación del lado del cliente) a un proyecto de Astro existente. Puedes hacer un fork y usar esa base de código localmente, o completar el tutorial en el navegador [editando el código del tutorial del blog en StackBlitz](https://stackblitz.com/github/withastro/blog-tutorial-demo/tree/complete?file=src%2Fpages%2Findex.astro).

En su lugar, puedes seguir estos pasos con tu propio proyecto de Astro, pero deberás ajustar las instrucciones para tu base de código.

Recomendamos utilizar nuestro proyecto de ejemplo para completar este breve tutorial primero. Luego, puedes aplicar lo que has aprendido para crear view transitions en tu propio proyecto.

## Código del Tutorial Crear un Blog

En el [tutorial introductorio Crear un Blog](/es/tutorial/0-introduction/), aprendiste sobre la [navegación incorporada basada en archivos](/es/guides/routing/#rutas-estáticas) de Astro: cualquier archivo `.astro`, `.md` o `.mdx` en cualquier lugar dentro de la carpeta `src/pages/` se convertía automáticamente en una nueva página en tu sitio.

Para navegar entre estas páginas, utilizaste el elemento HTML estándar `<a>`. Por ejemplo, para crear un enlace a tu página "Acerca de", agregaste `<a href="/about/">Acerca de</a>` en la cabecera de tu página. Cuando un visitante de tu sitio hacía clic en ese enlace, el navegador se actualizaba y cargaba una nueva página con contenido completamente nuevo.

## Navegación de página completa vs. enrutamiento del lado del cliente (modo SPA)

Cuando un navegador se actualiza y carga una nueva página, no hay continuidad entre la página antigua y la nueva. Durante el enrutamiento del lado del cliente, se muestra una nueva página sin una actualización completa del navegador.

El enrutamiento del lado del cliente es una característica de los sitios de aplicaciones de una sola página (SPA), donde todo el sitio o aplicación es "una página" de JavaScript cuyo contenido se actualiza en función de la interacción del visitante.

Debido a que cada nueva página no requiere una actualización completa del navegador, el enrutamiento del lado del cliente te permite controlar las transiciones de página de varias maneras. Los **elementos persistentes**, como un encabezado común de la página, no tienen que ser completamente vuelto a renderizar en la pantalla. La transición de una página a otra puede parecer mucho más fluida. Además, el estado puede conservarse, ¡lo que te permite transferir valores de una página a la siguiente o incluso mantener un video reproduciéndose mientras tus visitantes navegan por las páginas!
 
Hay momentos en los que querrás o necesitarás una actualización completa del navegador. Por ejemplo, cuando un enlace lleva a un visitante a un documento `.pdf`, necesitarás que el navegador cargue esa nueva página desde el servidor. Incluso con las view transitions habilitadas en tu proyecto de Astro, podrás especificar cómo debería navegar el navegador tanto de forma predeterminada como de forma específica para cada enlace, incluso eligiendo no utilizar enrutamiento del lado del cliente en absoluto.

Lee más sobre las [view transitions de Astro](/es/guides/view-transitions/) en nuestra guía, o sumérgete en las instrucciones a continuación para ampliar el blog con view transitions.

<Box icon="question-mark">
### Pon a prueba tus conocimientos

1. Añadiendo view transitions a mi sitio de Astro...

    <MultipleChoice>
      <Option>
        Requiere más de 2 líneas de código para implementarse en todo el sitio de forma predeterminada
      </Option>
      <Option isCorrect>
        Cambia el tipo predeterminado de navegación de página en una página que contiene el enrutador `<ViewTransitions />` en su `<head>`
      </Option>
      <Option>
        No agrega de vuelta las características de accesibilidad normalmente proporcionadas por el navegador, como el anuncio de ruta y el respeto a `prefers-reduced-motion`
      </Option>
    </MultipleChoice>

2. ¿Cuál **no** es un beneficio de las view transitions de Astro?

    <MultipleChoice>
      <Option isCorrect>
         Enviar un poco de JavaScript adicional al navegador para el enrutamiento del lado del cliente
      </Option>
      <Option>
        La opción de persistir elementos y componentes individuales mientras un visitante accede a una nueva página
      </Option>
      <Option>
        Controlar qué tipo de navegación utilizar de manera específica para cada enlace
      </Option>
    </MultipleChoice>

3. El enrutador de las view transitions...
    <MultipleChoice>
      <Option>
        Requiere que utilice un framework UI como React
      </Option>
      <Option>
        No está listo para sitios de producción
      </Option>
      <Option isCorrect>
        Incluye un comportamiento de respaldo para navegadores que aún no admiten completamente las view transitions
      </Option>
    </MultipleChoice>

</Box>

## Ampliando el tutorial del blog con view transitions

Los pasos a continuación te muestran cómo ampliar el producto final del tutorial "Crear un Blog" al agregar enrutamiento del lado del cliente para mejorar las view transitions.

### Actualizar dependencias

<Steps>
1. Actualiza a la última versión de Astro y todas las integraciones a sus versiones más recientes ejecutando los siguientes comandos en tu terminal:

    <PackageManagerTabs>
      <Fragment slot="npm">
      ```shell
      # Actualizar a Astro v4.x
      npm install astro@latest

      # Ejemplo: actualizar la integración de Preact en el tutorial del blog
      npm install @astrojs/preact@latest
      ```
      </Fragment>
      <Fragment slot="pnpm">
      ```shell
      # Actualizar a Astro v4.x
      pnpm add astro@latest

     # Ejemplo: actualizar la integración de Preact en el tutorial del blog
      pnpm add @astrojs/preact@latest
      ```
      </Fragment>
      <Fragment slot="yarn">
      ```shell
      # Actualizar a Astro v4.x
      yarn add astro@latest

      # Ejemplo: actualizar la integración de Preact en el tutorial del blog
      yarn add @astrojs/preact@latest
      ```
      </Fragment>
    </PackageManagerTabs>

    :::tip
    Si estás utilizando tu propio proyecto, asegúrate de actualizar cualquier dependencia que hayas instalado. La base de código del tutorial de ejemplo del blog solo utiliza la integración de Preact.
    :::
</Steps>

### Añade el enrutador `<ViewTransitions />`

<Steps>
2. Importa y añade el componente `<ViewTransitions />` al `<head>` de la plantilla de tu página.

    En el ejemplo del tutorial del blog, el elemento `<head>` se encuentra en `src/layouts/BaseLayout.astro`. Primero, el enrutador `ViewTransitions` debe importarse en el frontmatter del componente. Luego, agrega el componente de enrutamiento dentro del elemento `<head>`.

    ```astro title="src/layouts/BaseLayout.astro" ins={2,15}
    ---
    import { ViewTransitions } from "astro:transitions";
    import Header from "../components/Header.astro";
    import Footer from "../components/Footer.astro";
    import "../styles/global.css";
    const { pageTitle } = Astro.props;
    ---
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>{pageTitle}</title>
        <ViewTransitions />
      </head>
      <body>
        <Header />
        <h1>{pageTitle}</h1>
        <slot />
        <Footer />
        <script>
          import "../scripts/menu.js";
        </script>
      </body>
    </html>
    ```

    ¡No es necesaria ninguna otra configuración para habilitar la navegación predeterminada del lado del cliente de Astro! Astro creará animaciones de página predeterminadas basadas en las similitudes entre la página antigua y la nueva, y también proporcionará un comportamiento de respaldo para navegadores no compatibles.

3. Navega entre páginas en la vista previa de tu sitio.

    Mira la vista previa de tu sitio **en una pantalla grande, como en modo escritorio**. Mientras te desplazas entre páginas en tu sitio, observa que el contenido de la página anterior parece desvanecerse a medida que el contenido de la nueva página se desvanece. Utiliza la [guía de view transitions](/es/guides/view-transitions/) para agregar un comportamiento personalizado si no estás satisfecho con las configuraciones predeterminadas.

    Mira la vista previa de tu sitio **en una pantalla más pequeña** y trata de utilizar el menú desplegable para navegar entre páginas. Observa que el menú dejará de funcionar después de cargar la primera página.
</Steps>

### Actualiza los scripts

Con las view transitions, algunos scripts pueden dejar de ejecutarse después de la navegación de página, a diferencia de lo que ocurre con las actualizaciones completas del navegador. Hay varios [eventos durante la navegación del lado del cliente a los que puedes escuchar](/es/guides/view-transitions/#eventos-del-ciclo-de-vida) y disparar eventos cuando ocurren. Los scripts en tu proyecto necesitarán ahora engancharse a dos eventos para ejecutarse en el momento adecuado durante la navegación de la página: [`astro:page-load`](/es/guides/view-transitions/#astropage-load) y [`astro:after-swap`](/es/guides/view-transitions/#astroafter-swap).

<Steps>
4. Haz que el script que controla el componente del menú móvil `<Hamburger />` esté disponible después de navegar a una nueva página.

     Para hacer que tu menú móvil sea interactivo después de navegar a una nueva página, agrega el siguiente código que escucha el evento `astro:page-load`, el cual se ejecuta al finalizar la navegación de la página, y en respuesta, ejecuta el script existente para que el menú desplegable funcione al hacer clic:

    ```js title="src/scripts/menu.js" ins={1,5}
    document.addEventListener('astro:page-load', () => {
      document.querySelector('.hamburger').addEventListener('click', () => {
        document.querySelector('.nav-links').classList.toggle('expanded');
      });
    });
    ```

5. Haz que el script que controla la alternancia de temas esté disponible después de la navegación de la página.

    El `<script>` que controla la alternancia de tema claro/oscuro se encuentra en el componente `<ThemeIcon />`. Para que la alternancia de tema siga funcionando en todas las páginas, elimina el atributo `is:inline` del script y agrega el mismo escuchador de eventos que en el ejemplo anterior, de modo que el evento `astro:page-load` pueda activar tu función existente.

    Actualiza la etiqueta de script existente para que tu función se ejecute en respuesta al evento `astro:page-load`, haciendo que la alternancia de tu tema sea interactiva después de que la nueva página esté completamente cargada y visible para el usuario.

    ```astro title="src/components/ThemeIcon.astro" ins={8,38} del="is:inline"
    ---
    ---
    <button id="themeToggle"> /* ... */ </button>

    <style> /* ... */ </style>

    <script is:inline>
      document.addEventListener('astro:page-load', () => {
        const theme = (() => {
          if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
            return localStorage.getItem("theme");
          }
          if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
            return "dark";
          }
          return "light";
        })();

        if (theme === "light") {
          document.documentElement.classList.remove("dark");
        } else {
          document.documentElement.classList.add("dark");
        }

        window.localStorage.setItem("theme", theme);

        const handleToggleClick = () => {
          const element = document.documentElement;
          element.classList.toggle("dark");

          const isDark = element.classList.contains("dark");
          localStorage.setItem("theme", isDark ? "dark" : "light");
        };

        document
          .getElementById("themeToggle")
          .addEventListener("click", handleToggleClick);
      });
    </script>
    ```
    Ahora, el alternador de temas es interactivo en cada página al utilizar el enrutador `<ViewTransitions />`, después de que la página ha terminado de cargarse.

6. Verifica el tema antes para evitar destellos en el modo oscuro.

    La alternancia de temas funciona en cada página, pero su script se carga al final del proceso de navegación, **después de que la nueva página se ha cargado completamente en el navegador**. Puede ocurrir un destello de la versión de tema claro del sitio antes de que se ejecute este script de alternancia de temas y verifique qué tema debe usar en la página.

    Para verificar y, si es necesario, establecer el modo oscuro más temprano en el proceso de navegación, crea una función que se ejecutará en respuesta al evento `astro:after-swap`. La siguiente función para verificar el tema oscuro en el `localStorage` del navegador se ejecutará **inmediatamente después de que la nueva página haya reemplazado a la antigua**, antes de que los elementos del DOM se pinten en la pantalla.

    Añade este nuevo script al componente `<ThemeIcon />`, además del script que controla la alternancia de temas.

    ```astro title="src/components/ThemeIcon.astro" ins={3-9}
    <script> ... <script>

    <script>
      document.addEventListener('astro:after-swap', () => {
        localStorage.theme === 'dark' 
        ? document.documentElement.classList.add("dark")
        : document.documentElement.classList.remove("dark");
      }); 
    </script>
    ```
</Steps>

    Ahora, cada cambio de página **que utilice el enrutador `<ViewTransitions />` para la navegación del lado del cliente** (y por lo tanto, tenga acceso al evento `astro:after-swap`) podrá detectar `theme: dark` desde el `localStorage` del navegador y actualizar la página actual en consecuencia antes de que se renderice para el espectador.

    <Box icon="question-mark">
      ### Pon a prueba tus conocimientos

      ¿Cuál es el orden correcto de los eventos después de que un visitante hace clic en un enlace para ir a una nueva página durante la navegación del lado del cliente?

          <MultipleChoice>
            <Option>
              1. `astro:after-swap`
              2. `astro:page-load`
              3. la nueva página es visible
            </Option>
            <Option isCorrect>
              1. `astro:after-swap`
              2. la nueva página es visible
              3. `astro:page-load`
            </Option>
            <Option>
              1. `astro:page-load`
              2. la nueva página es visible
              3. `astro:after-swap`
            </Option>
          </MultipleChoice>


      </Box>

### Personaliza las animaciones de transición

<Steps>
7. Cambia la animación predeterminada de `fade` a `slide` para el título de la página.

    Con las view transitions habilitadas, actualmente tienes una pequeña transición de desvanecimiento configurada para todas las animaciones de transición de página. Astro también proporciona una animación incorporada llamada `slide`. Para cambiar el tipo de animación para un solo elemento, agrega la directiva `transition:animate=""`.

    Por ejemplo, para hacer que los títulos de las páginas se deslicen en lugar de desvanecerse, agrega `transition:animate="slide"` al elemento `<h1>` en el BaseLayout:

    ```astro title="src/layouts/BaseLayout.astro" ins='transition:animate="slide"'
    ---
    import Header from "../components/Header.astro";
    import Footer from "../components/Footer.astro";
    import "../styles/global.css";
    import { ViewTransitions } from "astro:transitions";
    const { pageTitle } = Astro.props;
    ---

    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>{pageTitle}</title>
        <ViewTransitions />
      </head>
      <body>
        <Header />
        <h1 transition:animate="slide">{pageTitle}</h1>
        <slot />
        <Footer />
        <script>
          import "../scripts/menu.js";
        </script>
      </body>
    </html>
    ```
</Steps>

    En la vista previa de tu navegador, ahora verás que los títulos de las páginas se deslizan en la pantalla, mientras que otros elementos como el texto del cuerpo continúan desvaneciéndose.

    <Box icon="puzzle-piece">
      ### Inténtalo tú mismo: Haz que los enlaces de navegación se deslicen.

      Añade una directiva de animación para que el `<div>` en `Navigation.astro`, que contiene todos los enlaces del encabezado, se deslice al navegar por la página, siguiendo los [mismos pasos mencionados anteriormente](#personaliza-las-animaciones-de-transición).

      <details>
      <summary>Muéstrame el código.</summary>
      ```astro title="src/components/Navigation.astro" ins='transition:animate="slide"'
      ---
      ---
      <div transition:animate="slide" class="nav-links">
        <a href="/">Inicio</a>
        <a href="/about/">Acerca de</a>
        <a href="/blog/">Blog</a>
        <a href="/tags/" >Etiquetas</a>
      </div>
      ```
      </details>
    </Box>

    Verifica la vista previa de tu navegador y ahora tanto el título de la página como los enlaces del encabezado se deslizarán en cada navegación de página.

<Steps>
8. Añade una transición de desvanecimiento más larga a las descripciones de tus publicaciones en el blog.

    También puedes personalizar las animaciones integradas en Astro importándolas y luego proporcionando cualquier propiedad de animación CSS.

    Por ejemplo, para hacer que la descripción aparezca lentamente cuando navegas a una entrada de blog, importa la animación `fade` en tu plantilla para las entradas de blog en formato Markdown. Luego, agrega la directiva de transición para el `fade` de Astro con una duración de `2s`:

    ```astro title="src/layouts/MarkdownPostLayout.astro" ins={3} ins="transition:animate={fade({ duration: '2s' })}"
    ---
    import BaseLayout from "./BaseLayout.astro";
    import { fade } from "astro:transitions";
    const { frontmatter } = Astro.props;
    ---

    <BaseLayout pageTitle={frontmatter.title}>
      <p>{frontmatter.pubDate.slice(0, 10)}</p>
      <p transition:animate={fade({ duration: '2s' })} ><em>{frontmatter.description}</em></p>
      <p>Escrito por: {frontmatter.author}</p>
      <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
      <slot />
    </BaseLayout>
    ```
    Navega a cualquier entrada de blog en la vista previa de tu navegador y verás que la descripción aparece con una transición más lenta que el resto del texto.

    <ReadMore>Lee más acerca de las diferentes [directivas de transición](/es/guides/view-transitions/#directivas-de-transición) y la [personalización de animaciones](/es/guides/view-transitions/#personalizando-animaciones).</ReadMore>
</Steps>

### Fuerza una recarga completa del navegador para algunos enlaces

<Steps>
9. Evita el enrutamiento del lado del cliente y en su lugar exige al navegador que recargue cuando navegue a tu página Acerca de.

    En ocasiones, querrás que se realice una recarga completa del navegador cuando los visitantes hagan clic en ciertos enlaces. Por ejemplo, puede que estés vinculando a una página que no utiliza el enrutador `<ViewTransitions />`, o a un archivo directamente, como un archivo `.pdf`.

    Para lograr que tu navegador se actualice cada vez que hagas clic en el enlace de navegación para ir a tu página Acerca de, agrega el atributo `data-astro-reload` a la etiqueta `<a>` en tu componente `<Navigation />`. Esto anulará completamente el enrutador `<ViewTransitions />` y cualquier animación de las view transitions para este enlace en particular.

     ```astro title="src/components/Navigation.astro" ins='data-astro-reload'
      ---
      ---
      <div transition:animate="slide" class="nav-links">
        <a href="/">Inicio</a>
        <a href="/about/" data-astro-reload >Acerca de</a>
        <a href="/blog/">Blog</a>
        <a href="/tags/">Etiquetas</a>
      </div>
      ```

    Ahora, cuando hagas clic en el enlace de navegación hacia tu página Acerca de, no se producirán animaciones. Los enlaces y el título de la página no se deslizarán y el contenido de la página no se desvanecerá al navegar a tu página Acerca de **usando este enlace**.

10. Añade un enlace a tu página Acerca de desde tu nombre de autor en tu plantilla Markdown para las entradas del blog.

    `data-astro-reload` solo provoca una actualización completa del navegador al ir a una nueva página **desde el enlace al que se ha añadido**. No controla todas las instancias de navegación a tu página Acerca de.

    En tu compoente `<MarkdownPostLayout />`, agrega un enlace a tu página Acerca de en tu nombre de autor:

    ```astro title="src/layouts/MarkdownPostLayout.astro" ins='<a href="/about/">' ins="</a>"
    ---
    import BaseLayout from "./BaseLayout.astro";
    import { fade } from "astro:transitions";
    const { frontmatter } = Astro.props;
    ---

    <BaseLayout pageTitle={frontmatter.title}>
      <p>{frontmatter.pubDate.slice(0, 10)}</p>
      <p transition:animate={fade({ duration: '2s' })} ><em>{frontmatter.description}</em></p>
      <p>Escrito por: <a href="/about/">{frontmatter.author}</a></p>
      <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
      <slot />
    </BaseLayout>
    ```
</Steps>

    Si visitas cualquier entrada de blog en la vista previa del navegador y luego haces clic en el nombre del autor vinculado para ir a la página Acerca de, ¿cómo se ve la navegación de la página?

    <p>
      Cuando un visitante hace clic en un enlace a la página Acerca de desde una entrada de blog individual, el título de la página y los enlaces de navegación en la cabecera <Spoiler>se deslizan en la pantalla</Spoiler> porque <Spoiler>el atributo `data-astro-reload` no está configurado en estos enlaces.</Spoiler>
    </p>

¡Todavía hay mucho más por explorar! Consulta nuestra [Guía completa de View Transitions](/es/guides/view-transitions/) para descubrir más cosas que puedes hacer con las view transitions.

Para ver el ejemplo completo del tutorial de blog que utiliza view transitions, visita la [rama View Transitions](https://github.com/withastro/blog-tutorial-demo/tree/view-transitions) en el repositorio del tutorial.
